package bennyhuo.reflect

import java.lang.reflect.ParameterizedType
import kotlin.reflect.full.declaredFunctions
import kotlin.reflect.jvm.javaMethod
import kotlin.reflect.jvm.reflect

interface Api {
    fun getUsers(): List<Int>

    fun getUserMap1(): Map<Int, Boolean>

    fun getUserMap2(): Map<Long, Boolean>
}


abstract class SuperType<T> {

    val subType by lazy {

        this::class.supertypes.first().arguments.forEach {
            println("子类泛型1：${it.type}")
        }
    }

    val subTypeJava by lazy {
        this.javaClass.genericSuperclass.safeAs<ParameterizedType>()?.actualTypeArguments?.forEach {
            println("子类泛型2：${it.typeName}")
        }
    }

}

class SubType : SuperType<String>()


fun main() {

    //1.获取接口方法的返回值泛型实参类型方式1
    Api::class.declaredFunctions.first { it.name == "getUsers" }
            .returnType.arguments.forEach {
        println("返回值泛型实参类型1：${it.type}")
    }

    //1.获取接口方法的返回值泛型实参类型方式2
//    Api::getUserMap1.returnType?.arguments?.forEach {
//        println("返回值泛型实参类型2：${it.type}")
//    }


    //1.获取接口方法的返回值泛型实参类型java方式
    Api::class.java.getDeclaredMethod("getUserMap2").genericReturnType.safeAs<ParameterizedType>()?.actualTypeArguments?.forEach {
        println("返回值泛型实参类型3：${it.typeName}")
    }

    //父类获取子类泛型实参
    val subType = SubType()
    subType.subType
    subType.subTypeJava

}

fun <T> Any.safeAs(): T? = this as? T
